#include "jamod_global.h"
#include "jamod_proxyimport.h"
#include <ini/iniparser.h>
#include <ini/dictionary.h>

dictionary *ini = NULL;

dictionary * JAMod_iniparser_load(const char * ininame);	// Custom INI loader ported from GSA code that allows one to use Q3 code --eez

void JAMod_LoadConfigFile(void)
{
	char buffer[MAX_QPATH];
	char path[MAX_QPATH];

	trap_Cvar_VariableBuffer("fs_game", buffer, MAX_QPATH);

	//strcpy(path, buffer);
	strcpy(path, "JAMod.ini");

	// Use the fs_game to get the INI file from the mod folder
	ini = JAMod_iniparser_load(path);
	if(!ini)
	{
		trap_Error("No JAMod INI file found!\n");
		return;
	}
	trap_Printf("JAMod INI loaded successfully.\n");
}

void JAMod_FreeFSMemory(void)
{
	//if(ini)
	//	iniparser_freedict(ini);
	// Don't free the above. It's likely going to be used by plugins later on.
}



__declspec(dllexport) int __fastcall JAMod_GetININumSections(void)
{
	if(ini)
		return iniparser_getnsec(ini);
	else
		return 0;
}

__declspec(dllexport) char* __fastcall JAMod_GetINISectionName(int sectionNum)
{
	if(ini)
		return iniparser_getsecname(ini, sectionNum);
	else
		return NULL;
}

__declspec(dllexport) char* __fastcall JAMod_GetINIString(char *key, char *defaultKey)
{
	if(ini)
		return iniparser_getstring(ini, key, defaultKey);
	else
		return NULL;
}

__declspec(dllexport) int __fastcall JAMod_GetINIInt(char *key, int defaultKey)
{
	if(ini)
		return iniparser_getint(ini, key, defaultKey);
	else
		return 0;
}

__declspec(dllexport) double __fastcall JAMod_GetINIDouble(char *key, double defaultKey)
{
	if(ini)
		return iniparser_getdouble(ini, key, defaultKey);
	else
		return 0;
}

__declspec(dllexport) int __fastcall JAMod_GetINIBoolean(char *key, int defaultKey)
{
	if(ini)
		return iniparser_getboolean(ini, key, defaultKey);
	else
		return 0;
}






#define ASCIILINESZ	(1024)
dictionary * JAMod_iniparser_load(const char * ininame)
{
    //FILE * in ;
	fileHandle_t f;

   // char line    [ASCIILINESZ+1] ;
    char section [ASCIILINESZ+1] ;
    char key     [ASCIILINESZ+1] ;
    char tmp     [ASCIILINESZ+1] ;
    char val     [ASCIILINESZ+1] ;

	char *buf;
	char *line;
	char loadPath[MAX_QPATH];

    int  last=0 ;
    int  len ;
    int  lineno=0 ;
    int  errs=0;

	//unsigned int newLen;

    dictionary * dict ;

	sprintf(loadPath, "%s", ininame);
	len = trap_FS_FOpenFile(loadPath, &f, FS_READ);

    /*if ((in=fopen(ininame, "r"))==NULL) {
        fprintf(stderr, "iniparser: cannot open %s\n", ininame);
        return NULL ;
    }*/
	if(!f){ //No file.
		trap_Printf("^1Failed to load INI file: %s\n", ininame);
		return NULL;
	}
	if( !len || len == -1){
		trap_Printf("^1Invalid length in INI file: %s\n", ininame);
		trap_FS_FCloseFile(f);
		return NULL;
	}
	if( (buf = (char*)malloc(len+1)) == 0){
		trap_Printf("^1Could not allocate enough memory for INI loading procedure.\n");
		return NULL;
	}

	trap_FS_Read(buf, len, f);
	trap_FS_FCloseFile(f);
	buf[len] = 0;

    dict = dictionary_new(0) ;
    if (!dict) {
        //fclose(in);
		trap_Printf("^1Could not create new *dictionary");
        return NULL ;
    }
    memset(section, 0, ASCIILINESZ);
    memset(key,     0, ASCIILINESZ);
    memset(val,     0, ASCIILINESZ);
    last=0 ;

	line = strtok(buf, "\n");
    while ( line != NULL ) {
        lineno++ ;
        len = (int)strlen(line)-1;
        //Safety check against buffer overflows
        /*if (line[len]!='\n') {
            //fprintf(stderr,
            //        "iniparser: input line too long in %s (%d)\n",
            //        ininame,
            //        lineno);
			Com_Printf("^1Ini input line too long in %s (%d)", ininame, lineno);
            dictionary_del(dict);
            //fclose(in);
            return NULL ;
        }*/
        //Get rid of \n and spaces at end of line
        /*while ((len>=0) &&
                ((line[len]=='\n') || (isspace(line[len])))) {
            line[len]=0 ;
            len-- ;
        }*/
        //Detect multi-line
        if (line[len]=='\\') {
            //Multi-line value
            last=len ;
            continue ;
        } else {
            last=0 ;
        }
        switch (iniparser_line(line, section, key, val)) {
            case LINE_EMPTY:
            case LINE_COMMENT:
            break ;

            case LINE_SECTION:
            errs = dictionary_set(dict, section, NULL);
            break ;

            case LINE_VALUE:
            //sprintf(tmp, "%s:%s", section, key);
			sprintf(tmp, "%s:%s", section, key);
            errs = dictionary_set(dict, tmp, val) ;
            break ;

            case LINE_ERROR:
            /*fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
                    ininame,
                    lineno);
            fprintf(stderr, "-> %s\n", line);*/
				trap_Printf("^1iniparser: syntax error in %s (%d):", ininame, lineno);
				trap_Printf("^1-> %s", line);
            errs++ ;
            break;

            default:
            break ;
        }
        //memset(line, 0, ASCIILINESZ);
        last=0;
        if (errs<0) {
            //fprintf(stderr, "iniparser: memory allocation failure\n");
			trap_Printf("^1Iniparser: Failed to allocate enough memory.");
            break ;
        }
		line = strtok(NULL, "\r\n");
    }

    if (errs) {
        dictionary_del(dict);
        dict = NULL ;
    }
//  fclose(in);
    return dict ;
}